L-SMASH Works H.264 QSVデコード
現在、L-SMASH Worksでh264_qsvを使用した場合、正常にデコードできない。
当該コードを削除した場合、Closed-GOPの動画は正常にシークできたが、Open-GOPの動画はシークに失敗した。
有効なデータを用い初期化しないといけない?
参考
コメント
用語
IDR(instantaneous decoding refresh)
なるほど、IDR(instantaneous decoding refresh) pictureで一区切りとなるのか。
ctx->has_b_framesを16に設定
cuvid系に対しても同じことをしているので、HWデコーダーの場合設定しておいた方が良いのか?
h264以外であればreturn
fake_idrの定義
0x00, 0x00, 0x00, 0x01はstart-codeと呼ばれるパターン
NALユニットごとに先頭だと示すためにつける同期のためのコードらしい RBSP(圧縮された生データ)
RBSPトレイリング・ビット(ユニットの長さをバイト単位に合わせるための調整用ビット)
0x65はNALヘッダ
0b01100101で0/11/00101に分けられる
0はforbidden_zero_bitで必ず0でないといけないフィールド
11はnal_ref_idcで参照ピクチャであるかのフィールド
11であるため、参照ピクチャである
00101はnal_unit_typeでNALUnitのtypeのフィールド
0b00101=5であるため、IDRピクチャである
変数定義
initializerのinit
コード内コメント箇所
/* Feed an initializer packet to the decoder since libavcodec does not append parameter sets to access units
* containing no IDR NAL units. Here we append parameter sets before the fake IDR NAL unit. Without this,
* MFXVideoDECODE_DecodeHeader will return MFX_ERR_MORE_DATA. */
日本語訳
libavcodecはIDR NALユニットを含まないアクセスユニットにはパラメータセットを付加しないので、デコーダーにイニシャライザーパケットを供給する。ここでは、ダミーのIDR NALユニットの前にパラメータセットを追加する。これを行わないと、MFXVideoDECODE_DecodeHeader は MFX_ERR_MORE_DATA を返す。
Intel VPLのドキュメントより
Before decoding the first frame, a sequence header (sequence parameter set in H.264 or sequence header in MPEG-2 and VC-1) must be present. The function skips any bitstreams before it encounters the new sequence header.
日本語訳
最初のフレームをデコードする前に、シーケンスヘッダ(H.264ではシーケンスパラメータセット、MPEG-2およびVC-1ではシーケンスヘッダ)が存在する必要がある。この関数は、新しいシーケンスヘッダに出会う前にビットストリームをスキップする。
結論?
1. QSV側はSPSを先にもらえない限り、デコードしない。(それはそうか)
2. シークごとにデコーダーの状態がクリアされるので、パケットごとにSPSを差し込む必要がある。
3. LSWではダミーIDR NALユニットをパケットごとに差し込み、libavcodecにSPSをダミーIDR NAL前に差し込ませることを促す。
4. これでパケットごとにSPSが挿入され、MFX_ERR_MORE_DATAが発生しなくなるが、ダミーIDR NALユニットが残っており、それが有効なスライスを持っていないため、エラーが発生する。
かな?
というわけで、
1. ダミーIDR NALユニットに有効なスライスを持たせるようにする
2. libavcodecがSPSを挿入した後に削除する
のいずれかをとればいい。FFmpeg APIの知識が薄いせいでわからん。